package propertymgmt.gui;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;

import propertymgmt.constants.Constants.PaymentType;
import propertymgmt.entities.Lease;
import propertymgmt.entities.Payment;
import propertymgmt.entities.Property;
import propertymgmt.entities.Tenant;
import propertymgmt.util.PropertiesManager;

/**
 * CreateNewPayment.java
 * 
 * Allows the user to create a new Payment to be associated with
 * an existing Lease and Tenant(s).
 *
 * @author Brian
 */
@SuppressWarnings("serial")
public class CreateNewPayment extends javax.swing.JInternalFrame {
	
    /** Creates new form CreateNewPayment */
    public CreateNewPayment() {
        initComponents();
        loadProperties();
    }
    
    public PaymentType getPaymentType(){
    	return (PaymentType) cmbo_payment.getSelectedItem();
    }
    
    public String getPaymentName(){
    	if(txt_paymentName.getText().trim().isEmpty()) return "";
    	return txt_paymentName.getText().trim();
    }
    
    public Date getDateReceived(){
    	return dc_datePaid.getDate();
    }
    
    public double getAmountReceived(){
    	if(ftxt_paymentAmt.getText().trim().isEmpty()) return 0;
    	return Double.parseDouble(ftxt_paymentAmt.getText().trim());
    }
    
    public ArrayList<Tenant> getAssociatedTenants(){
    	ArrayList<Tenant> tenants = new ArrayList<Tenant>();
    	
    	int numTenants = ((DefaultListModel<Tenant>)list_associatedTenants.getModel()).getSize();
    	
    	for(int i = 0; i < numTenants; i++){
    		tenants.add((Tenant) ((DefaultListModel<Tenant>)list_associatedTenants.getModel()).getElementAt(i));
    	}
    	
    	return tenants;
    }
    
    public Integer getPaymentMonth(){
    	if(pnl_rentMonthYear.isVisible()){
    		return rentMonthChooser.getMonth();
    	}else {
    		return null;
    	}
    }
    
    public Integer getPaymentYear(){
    	if(pnl_rentMonthYear.isVisible()){
    		return (Integer) cmbo_rentYear.getSelectedItem();
    	}else {
    		return null;
    	}
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        pnl_rentMonthYear = new javax.swing.JPanel();
        pnl_rentMonthYear.setVisible(false);
        rentMonthChooser = new com.toedter.calendar.JMonthChooser();
        cmbo_rentYear = new javax.swing.JComboBox<Integer>();
        jPanel2 = new javax.swing.JPanel();
        cmbo_payment = new javax.swing.JComboBox<PaymentType>();
        jPanel3 = new javax.swing.JPanel();
        cmbo_property = new javax.swing.JComboBox<Property>();
        jPanel4 = new javax.swing.JPanel();
        cmbo_lease = new javax.swing.JComboBox<Lease>();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jPanel5 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        list_associatedTenants = new javax.swing.JList<Tenant>();
        btn_addTenant = new javax.swing.JButton();
        btn_removeTenant = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        list_tenants = new javax.swing.JList<Tenant>();
        txt_paymentName = new javax.swing.JTextField();
        ftxt_paymentAmt = new javax.swing.JFormattedTextField();
        dc_datePaid = new com.toedter.calendar.JDateChooser();
        btn_createPayment = new javax.swing.JButton();

        setClosable(true);
        setIconifiable(true);
        setTitle("Create New Payment");
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
        
        pnl_rentMonthYear.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Choose Rent Month / Year", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 11))); // NOI18N
        pnl_rentMonthYear.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
        pnl_rentMonthYear.add(rentMonthChooser, new org.netbeans.lib.awtextra.AbsoluteConstraints(50, 30, 130, -1));

        for(int i = 1990; i <= Calendar.getInstance().get(Calendar.YEAR); i++){
        	((DefaultComboBoxModel<Integer>) cmbo_rentYear.getModel()).addElement(i);
        }
        
        pnl_rentMonthYear.add(cmbo_rentYear, new org.netbeans.lib.awtextra.AbsoluteConstraints(180, 30, 70, 20));

        jPanel1.add(pnl_rentMonthYear, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 310, 300, 80));

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Choose Payment Type", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 11))); // NOI18N
        jPanel2.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
        
        cmbo_payment.setModel(new DefaultComboBoxModel<PaymentType>());
        
        for(PaymentType paymentType : PaymentType.values()){
        	((DefaultComboBoxModel<PaymentType>)cmbo_payment.getModel()).addElement(paymentType);
        }
        
        cmbo_payment.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmbo_paymentActionPerformed(evt);
            }
        });
        jPanel2.add(cmbo_payment, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 30, 260, -1));

        jPanel1.add(jPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 210, 300, 80));

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Choose Property", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 11))); // NOI18N
        jPanel3.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        cmbo_property.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmbo_propertyActionPerformed(evt);
            }
        });
        jPanel3.add(cmbo_property, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 30, 260, -1));

        jPanel1.add(jPanel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 10, 300, 80));

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Choose Lease Term", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 11))); // NOI18N
        jPanel4.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        cmbo_lease.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmbo_leaseActionPerformed(evt);
            }
        });
        jPanel4.add(cmbo_lease, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 30, 260, -1));

        jPanel1.add(jPanel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 110, 300, 80));

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel1.setText("Payment Name");
        jPanel1.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(390, 20, -1, -1));

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel2.setText("Payment Amount");
        jPanel1.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(390, 70, -1, -1));

        jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel3.setText("Date Paid");
        jPanel1.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(390, 120, -1, -1));

        jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Associate Payment With Tenant(s)", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 11))); // NOI18N
        jPanel5.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        list_associatedTenants.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                list_associatedTenantsValueChanged(evt);
            }
        });
        list_associatedTenants.setModel(new DefaultListModel<Tenant>());
        jScrollPane1.setViewportView(list_associatedTenants);

        jPanel5.add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(260, 20, 170, 210));

        btn_addTenant.setText(">>");
        btn_addTenant.setEnabled(false);
        btn_addTenant.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_addTenantActionPerformed(evt);
            }
        });
        jPanel5.add(btn_addTenant, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 50, 60, -1));

        btn_removeTenant.setText("<<");
        btn_removeTenant.setEnabled(false);
        btn_removeTenant.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_removeTenantActionPerformed(evt);
            }
        });
        jPanel5.add(btn_removeTenant, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 90, 60, -1));

        list_tenants.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                list_tenantsValueChanged(evt);
            }
        });
        list_tenants.setModel(new DefaultListModel<Tenant>());
        jScrollPane2.setViewportView(list_tenants);

        jPanel5.add(jScrollPane2, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 20, 170, 210));

        jPanel1.add(jPanel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(370, 160, 440, 250));
        jPanel1.add(txt_paymentName, new org.netbeans.lib.awtextra.AbsoluteConstraints(520, 20, 280, -1));

        ftxt_paymentAmt.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("###0.###"))));
        jPanel1.add(ftxt_paymentAmt, new org.netbeans.lib.awtextra.AbsoluteConstraints(520, 70, 280, -1));
        jPanel1.add(dc_datePaid, new org.netbeans.lib.awtextra.AbsoluteConstraints(520, 120, 280, -1));

        btn_createPayment.setText("Create Payment");
        btn_createPayment.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	btn_createPaymentActionPerformed(evt);
            }
        });
        jPanel1.add(btn_createPayment, new org.netbeans.lib.awtextra.AbsoluteConstraints(700, 430, -1, -1));

        getContentPane().add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 830, 470));

        pack();
    }// </editor-fold>
    
    private Property getCurrentChosenProperty(){
    	return (Property) cmbo_property.getSelectedItem();
    }
    
    private Lease getCurrentChosenLease(){
    	return (Lease) cmbo_lease.getSelectedItem();
    }
    
    private void clearLeases(){
    	cmbo_lease.removeAllItems();
    }
    
    private void clearTenants(){
    	((DefaultListModel<Tenant>)list_tenants.getModel()).clear();
    	((DefaultListModel<Tenant>)list_associatedTenants.getModel()).clear();
    }
    
    private void cmbo_propertyActionPerformed(java.awt.event.ActionEvent evt) {
    	loadLeases();
    }

    private void cmbo_leaseActionPerformed(java.awt.event.ActionEvent evt) {
    	loadTenants();
    	
//    	Lease currentLease = getCurrentChosenLease();
//    	if(currentLease != null){
//    		dc_datePaid.setMinSelectableDate(currentLease.getLeaseStartDate());
//    		dc_datePaid.setMaxSelectableDate(currentLease.getLeaseEndDate());
//    	}
    }

    private void cmbo_paymentActionPerformed(java.awt.event.ActionEvent evt) {
    	Object paymentTypeObj = cmbo_payment.getSelectedItem();
    	
    	if(paymentTypeObj != null){
    		PaymentType paymentType = (PaymentType) paymentTypeObj;
    		pnl_rentMonthYear.setVisible(paymentType.equals(PaymentType.RENT));
    	}
    }

    private void btn_addTenantActionPerformed(java.awt.event.ActionEvent evt) {
    	Property currentProperty = getCurrentChosenProperty();
    	Lease currentLease = getCurrentChosenLease();
    	
        if(currentProperty != null && currentLease != null){
        	Tenant selectedTenant = (Tenant) list_tenants.getSelectedValue();
        	
        	for(Tenant tenant : currentLease.getTenants()){
        		if(tenant.equals(selectedTenant)){
        			((DefaultListModel<Tenant>)list_associatedTenants.getModel()).addElement(tenant);
					((DefaultListModel<Tenant>)list_tenants.getModel()).removeElement(tenant);
					break;
        		}
        	}
        }
    }

    private void btn_removeTenantActionPerformed(java.awt.event.ActionEvent evt) {
    	Property currentProperty = getCurrentChosenProperty();
    	Lease currentLease = getCurrentChosenLease();
    	
        if(currentProperty != null && currentLease != null){
        	Tenant selectedTenant = (Tenant) list_associatedTenants.getSelectedValue();
        	
        	for(Tenant tenant : currentLease.getTenants()){
        		if(tenant.equals(selectedTenant)){
        			((DefaultListModel<Tenant>)list_associatedTenants.getModel()).removeElement(tenant);
					((DefaultListModel<Tenant>)list_tenants.getModel()).addElement(tenant);
					break;
        		}
        	}
        }
    }
    
    private void btn_createPaymentActionPerformed(java.awt.event.ActionEvent evt) {
    	if(checkFields()){
    		Payment newPayment = new Payment(getPaymentType(), getPaymentName(), getDateReceived(),
    				getAmountReceived(), getAssociatedTenants(), getPaymentMonth(), getPaymentYear());
    		
        	Lease currentLease = getCurrentChosenLease();
        	
            if(currentLease != null){
            	currentLease.addPayment(newPayment);
            	PropertiesManager.getInstance().saveDbState();
            }
    	}else {
    		JOptionPane.showMessageDialog(this, "Payment not created - please check fields.\n Payment types RENT" +
    				" and FINES must have associated tenants.");
    	}
    }
    
    private void list_tenantsValueChanged(javax.swing.event.ListSelectionEvent evt) {
        if(!btn_addTenant.isEnabled()){
        	btn_addTenant.setEnabled(true);
        }
    }

    private void list_associatedTenantsValueChanged(javax.swing.event.ListSelectionEvent evt) {
    	if(!btn_removeTenant.isEnabled()){
    		btn_removeTenant.setEnabled(true);
        }
    }
    
    private void loadProperties(){
    	List<Property> allProperties = PropertiesManager.getInstance().getAllProperties();
    	
    	if(allProperties != null && allProperties.size() != 0){
    		for(Property property : allProperties){
    			((DefaultComboBoxModel<Property>)cmbo_property.getModel()).addElement(property);    			
    		}
    	}
    }
    
    private void loadLeases(){
    	Property currentProperty = getCurrentChosenProperty();
    	
    	if(currentProperty != null){
    		clearLeases();
    		
    		for(Lease lease : currentProperty.getLeases()){
    			((DefaultComboBoxModel<Lease>)cmbo_lease.getModel()).addElement(lease);    			
    		}
    	}
    }
    
    private void loadTenants(){
    	Lease currentLease = getCurrentChosenLease();
    	
    	if(currentLease != null){
    		clearTenants();
    		
    		for(Tenant tenant : currentLease.getTenants()){
    			((DefaultListModel<Tenant>)list_tenants.getModel()).addElement(tenant);
    		}
    	}
    }
    
    private boolean checkFields(){
    	boolean passed = getDateReceived() != null;
    	passed &= getAmountReceived() != 0;
    	
    	if(getPaymentType().equals(PaymentType.RENT) || 
    			getPaymentType().equals(PaymentType.FINE)){
    		passed &= getAssociatedTenants().size() > 0;
    	}
    	
    	return passed;
    }


    // Variables declaration - do not modify
    private javax.swing.JButton btn_addTenant;
    private javax.swing.JButton btn_removeTenant;
    private javax.swing.JComboBox<Lease> cmbo_lease;
    private javax.swing.JComboBox<PaymentType> cmbo_payment;
    private javax.swing.JComboBox<Property> cmbo_property;
    private javax.swing.JComboBox<Integer> cmbo_rentYear;
    private com.toedter.calendar.JDateChooser dc_datePaid;
    private javax.swing.JFormattedTextField ftxt_paymentAmt;
    private javax.swing.JButton btn_createPayment;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JList<Tenant> list_associatedTenants;
    private javax.swing.JList<Tenant> list_tenants;
    private javax.swing.JTextField txt_paymentName;
    private javax.swing.JPanel pnl_rentMonthYear;
    private com.toedter.calendar.JMonthChooser rentMonthChooser;
    // End of variables declaration
}